<!DOCTYPE html>
<html lang="zh" data-direction="ltr">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta
      name="keywords"
      content="Go-Micro, Micro, 中文, Go-Micro教程, Go-Micro资源"
    />
    <meta
      name="description"
      content="Micro 中国站，只为原生中文资源"
    />
    <title>Go Config 配置库 - Micro 中国</title>
    <meta data-rh="true" property="og:type" content="website"/><meta data-rh="true" property="og:image" content=""/><meta data-rh="true" property="og:title" content="Go Config 配置库 - Micro 中国"/><meta data-rh="true" name="description" content="Go Config 作为配置库，它也是动态的可插拔的。"/>
    <link
      rel="icon"
      href="https://avatars2.githubusercontent.com/u/20906580?s=60&v=4"
      type="image/x-icon"
    />
    
    <link rel="stylesheet" type="text/css" href="/index-47dfeecd.css" />
    
    <style id="nprogress-style">
      #nprogress {
        display: none;
      }
    </style>
    <link rel="stylesheet/less" type="text/css" href="/color.less" />
    <script src="https://polyfill.alicdn.com/polyfill.min.js?features=default,es2015,Intl"></script>
    <script>
      (function () {
        function isLocalStorageNameSupported() {
          var testKey = 'test';
          var storage = window.localStorage;
          try {
            storage.setItem(testKey, '1');
            storage.removeItem(testKey);
            return true;
          } catch (error) {
            return false;
          }
        }
        // 优先级提高到所有静态资源的前面，语言不对，加载其他静态资源没意义
        var pathname = location.pathname;

        function isZhCN(pathname) {
          return /-cn\/?$/.test(pathname);
        }
        function getLocalizedPathname(path, zhCN) {
          var pathname = path.startsWith('/') ? path : '/' + path;
          if (!zhCN) {
            // to enUS
            return /\/?index-cn/.test(pathname) ? '/' : pathname.replace('-cn', '');
          } else if (pathname === '/') {
            return '/index-cn';
          } else if (pathname.endsWith('/')) {
            return pathname.replace(/\/$/, '-cn/');
          }
          return pathname + '-cn';
        }

        // 兼容旧的 URL， `?locale=...`
        var queryString = location.search;
        if (queryString) {
          var isZhCNConfig = queryString.indexOf('zh-CN') > -1;
          if (isZhCNConfig && !isZhCN(pathname)) {
            location.pathname = getLocalizedPathname(pathname, isZhCNConfig);
          }
        }

        // 首页无视链接里面的语言设置 https://github.com/ant-design/ant-design/issues/4552
        if (isLocalStorageNameSupported() && (pathname === '/' || pathname === '/index-cn')) {
          var lang =
            (window.localStorage && localStorage.getItem('locale')) ||
            ((navigator.language || navigator.browserLanguage).toLowerCase() === 'zh-cn'
              ? 'zh-CN'
              : 'en-US');
          // safari is 'zh-cn', while other browser is 'zh-CN';
          if ((lang === 'zh-CN') !== isZhCN(pathname)) {
            location.pathname = getLocalizedPathname(pathname, lang === 'zh-CN');
          }
        }
        document.documentElement.className += isZhCN(pathname) ? 'zh-cn' : 'en-us';
      })();
    </script>
  </head>
  <body>
    <div id="react-content">
      <div class="page-wrapper"><header id="header" class="clearfix"><div class="ant-row" style="flex-flow:nowrap;height:64px"><div class="ant-col ant-col-xs-24 ant-col-sm-24 ant-col-md-6 ant-col-lg-6 ant-col-xl-5 ant-col-xxl-4"><h1><a id="logo" href="/index-cn"><img alt="logo" src=""/>Micro 中国</a></h1></div><div class="ant-col menu-row ant-col-xs-0 ant-col-sm-0 ant-col-md-18 ant-col-lg-18 ant-col-xl-19 ant-col-xxl-20"><div id="search-box" class=""><span role="img" aria-label="search" class="anticon anticon-search"><svg viewBox="64 64 896 896" focusable="false" class="" data-icon="search" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"></path></svg></span><input type="text" placeholder="在 Micro China 中搜索" class="ant-input" value=""/></div><ul class="ant-menu menu-site ant-menu-light ant-menu-root ant-menu-horizontal" id="nav" direction="ltr" role="menu"><li class="ant-menu-submenu ant-menu-submenu-horizontal ant-menu-overflowed-submenu" style="display:none" role="menuitem"><div class="ant-menu-submenu-title" role="button" aria-expanded="false" aria-haspopup="true"><span>···</span><i class="ant-menu-submenu-arrow"></i></div></li><li class="ant-menu-item ant-menu-item-only-child" role="menuitem"><a href="/docs/micro/introduce-cn">文档</a></li><li class="ant-menu-submenu ant-menu-submenu-horizontal ant-menu-overflowed-submenu" style="display:none" role="menuitem"><div class="ant-menu-submenu-title" role="button" aria-expanded="false" aria-haspopup="true"><span>···</span><i class="ant-menu-submenu-arrow"></i></div></li><li class="ant-menu-item ant-menu-item-only-child" role="menuitem"><a href="/components/button-cn/">插件</a></li><li class="ant-menu-submenu ant-menu-submenu-horizontal ant-menu-overflowed-submenu" style="display:none" role="menuitem"><div class="ant-menu-submenu-title" role="button" aria-expanded="false" aria-haspopup="true"><span>···</span><i class="ant-menu-submenu-arrow"></i></div></li><li class="ant-menu-item ant-menu-item-only-child" role="menuitem"><a href="/docs/resources-cn">资源</a></li><li class="ant-menu-submenu ant-menu-submenu-horizontal ant-menu-overflowed-submenu" style="visibility:hidden;position:absolute" role="menuitem"><div class="ant-menu-submenu-title" role="button" aria-expanded="false" aria-haspopup="true"><span>···</span><i class="ant-menu-submenu-arrow"></i></div></li></ul><button type="button" class="ant-btn header-button header-lang-button ant-btn-sm">繁体中文</button><button type="button" class="ant-btn header-button ant-dropdown-trigger ant-btn-sm">更多<span role="img" aria-label="down" style="font-size:9px;margin-left:2px;vertical-align:middle;margin-top:-1px" class="anticon anticon-down"><svg viewBox="64 64 896 896" focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></button><span id="github-btn" class="github-btn"><a class="gh-btn" href="//github.com/micro/go-micro/" target="_blank"><span class="gh-ico" aria-hidden="true"></span><span class="gh-text">Star</span></a><a class="gh-count" target="_blank" href="//github.com/micro/go-micro/stargazers/"></a></span></div></div></header><div class="main-wrapper"><div class="ant-row"><div class="ant-col main-menu ant-col-xs-24 ant-col-sm-24 ant-col-md-6 ant-col-lg-6 ant-col-xl-5 ant-col-xxl-4"><div><div class=""><section class="main-menu-inner"><ul class="ant-menu aside-container menu-site ant-menu-light ant-menu-root ant-menu-inline" direction="ltr" role="menu"></ul></section></div></div></div><div class="ant-col ant-col-xs-24 ant-col-sm-24 ant-col-md-18 ant-col-lg-18 ant-col-xl-19 ant-col-xxl-20"><section class="main-container"><article class="markdown"><div><h1>Go Config 配置库<a class="edit-button" href="https://github.com/ant-design/ant-design/edit/master/docs/micro/go-config.zh-CN.md" target="_blank" rel="noopener noreferrer"><span role="img" aria-label="edit" class="anticon anticon-edit"><svg viewBox="64 64 896 896" focusable="false" class="" data-icon="edit" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M257.7 752c2 0 4-.2 6-.5L431.9 722c2-.4 3.9-1.3 5.3-2.8l423.9-423.9a9.96 9.96 0 000-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2a33.5 33.5 0 009.4 29.8c6.6 6.4 14.9 9.9 23.8 9.9zm67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z"></path></svg></span></a></h1></div><div class="toc-affix"><div class=""><ul class="toc"><li><a class="bisheng-toc-h2" href="#特性" title="特性">特性</a></li><li><a class="bisheng-toc-h2" href="#开始" title="开始">开始</a></li><li><a class="bisheng-toc-h2" href="#Sources" title="Sources">Sources</a></li><li><a class="bisheng-toc-h2" href="#Encoder" title="Encoder">Encoder</a></li><li><a class="bisheng-toc-h2" href="#Reader" title="Reader">Reader</a></li><li><a class="bisheng-toc-h2" href="#Config" title="Config">Config</a></li><li><a class="bisheng-toc-h2" href="#使用方式" title="使用方式">使用方式</a></li><li><a class="bisheng-toc-h2" href="#常见问题" title="常见问题">常见问题</a></li></ul></div></div><section class="markdown"><p>Go Config 作为配置库，它也是动态的可插拔的。</p><p>大多数的应用配置都是放在静态文件中或者用复杂的逻辑从不同的文件中加载。</p><p>Go-config 就简单得多，可插拔且可合并。</p><h2 id="特性"><span>特性</span><a href="#特性" class="anchor">#</a></h2><ul><li><p><strong>动态加载</strong> - 动态按时按需从多资源加载配置。Go Config 会在后台监视配置资源，动态在内存中合并、更新。</p></li><li><p><strong>可插拔资源</strong> - 可选择从任意数量的资源中加载、合并配置，后台资源在内部被抽象成标准格式并通过编码器解码。资源可以是环境变量、参数 flag、文件、etcd、k8s configmap 等等。</p></li><li><p><strong>可合并配置</strong> - 假设指定了多个配置源，格式不限，它们会被合并划一。 这样大大简化了配置的优先级与环境的变动。</p></li><li><p><strong>观察变动</strong> - 可以选择观测指定配置值的变动。使用 Go Config 观测器热加载，可以随时查看配置值的变动情况。</p></li><li><p><strong>安全修复</strong> - 某些情况如配置加载失败或者被擦除时，可以指定回退值。这可以保证在发生事故时，我们能读取完整的默认值。</p></li></ul><h2 id="开始"><span>开始</span><a href="#开始" class="anchor">#</a></h2><ul><li><p><a href="#source">Source</a> - 后台获取加载的位置</p></li><li><p><a href="#encoder">Encoder</a> - 负责处理资源配置编码、解码</p></li><li><p><a href="#reader">Reader</a> - 将多个编码处理后的资源合并成单一的格式</p></li><li><p><a href="#config">Config</a> - 配置管理器，负责管理多资源</p></li><li><p><a href="#usage">Usage</a> - go-config 使用示例</p></li><li><p><a href="#faq">FAQ</a> - 常见问题及回答</p></li><li><p><a href="#todo">TODO</a> - 将来要开发的任务或特性</p></li></ul><h2 id="Sources"><span>Sources</span><a href="#Sources" class="anchor">#</a></h2><p><code>Source</code>也即后台加载的配置，同时可以使用多资源。</p><p>支持以下格式：</p><ul><li><p><a href="https://github.com/micro/go-micro/tree/master/config/source/cli">cli</a> - read from parsed CLI flags</p></li><li><p><a href="https://github.com/micro/go-micro/tree/master/config/source/consul">consul</a> - read from consul</p></li><li><p><a href="https://github.com/micro/go-micro/tree/master/config/source/env">env</a> - read from environment variables</p></li><li><p><a href="https://github.com/micro/go-micro/tree/master/config/source/etcd">etcd</a> - read from etcd v3</p></li><li><p><a href="https://github.com/micro/go-micro/tree/master/config/source/file">file</a> - read from file</p></li><li><p><a href="https://github.com/micro/go-micro/tree/master/config/source/flag">flag</a> - read from flags</p></li><li><p><a href="https://github.com/micro/go-micro/tree/master/config/source/memory">memory</a> - read from memory</p></li></ul><p>也存在一些社区支持的插件：</p><ul><li><p><a href="https://github.com/micro/go-plugins/tree/master/config/source/configmap">configmap</a> - read from k8s configmap</p></li><li><p><a href="https://github.com/micro/go-plugins/tree/master/config/source/grpc">grpc</a> - read from grpc server</p></li><li><p><a href="https://github.com/micro/go-plugins/tree/master/config/source/runtimevar">runtimevar</a> - read from Go Cloud Development Kit runtime variable</p></li><li><p><a href="https://github.com/micro/go-plugins/tree/master/config/source/url">url</a> - read from URL</p></li><li><p><a href="https://github.com/micro/go-plugins/tree/master/config/source/vault">vault</a> - read from Vault server</p></li></ul><p>TODO:</p><ul><li><p>git url</p></li></ul><h3 id="ChangeSet-变更集"><span>ChangeSet 变更集</span><a href="#ChangeSet-变更集" class="anchor">#</a></h3><p>Sources 以变更集的方式返回配置。对于多个后台配置，变更集是单一的内部抽象。</p><pre class="language-go"><code><span class="token keyword">type</span> ChangeSet <span class="token keyword">struct</span> <span class="token punctuation">{</span>
	<span class="token comment" spellcheck="true">// Raw encoded config data</span>
	Data      <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span>
	<span class="token comment" spellcheck="true">// MD5 checksum of the data</span>
	Checksum  <span class="token builtin">string</span>
	<span class="token comment" spellcheck="true">// Encoding format e.g json, yaml, toml, xml</span>
	Format    <span class="token builtin">string</span>
	<span class="token comment" spellcheck="true">// Source of the config e.g file, consul, etcd</span>
	Source    <span class="token builtin">string</span>
	<span class="token comment" spellcheck="true">// Time of loading or update</span>
	Timestamp time<span class="token punctuation">.</span>Time
<span class="token punctuation">}</span></code></pre><h2 id="Encoder"><span>Encoder</span><a href="#Encoder" class="anchor">#</a></h2><p><code>Encoder</code>负责资源配置编码、解码。后台资源可能会存在不同的格式，编码器负责处理不同的格式，默认的格式是 Json。</p><p>编码器支持以下格式：</p><ul><li><p>json</p></li><li><p>yaml</p></li><li><p>toml</p></li><li><p>xml</p></li><li><p>hcl</p></li></ul><h2 id="Reader"><span>Reader</span><a href="#Reader" class="anchor">#</a></h2><p><code>Reader</code>负责把多个 changeset 集合并成一个可查询的值集。</p><pre class="language-go"><code><span class="token keyword">type</span> Reader <span class="token keyword">interface</span> <span class="token punctuation">{</span>
	<span class="token comment" spellcheck="true">// Merge multiple changeset into a single format</span>
	<span class="token function">Merge</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token operator">*</span>source<span class="token punctuation">.</span>ChangeSet<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>source<span class="token punctuation">.</span>ChangeSet<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span>
	<span class="token comment" spellcheck="true">// Return return Go assertable values</span>
	<span class="token function">Values</span><span class="token punctuation">(</span><span class="token operator">*</span>source<span class="token punctuation">.</span>ChangeSet<span class="token punctuation">)</span> <span class="token punctuation">(</span>Values<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span>
	<span class="token comment" spellcheck="true">// Name of the reader e.g a json reader</span>
	<span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">string</span>
<span class="token punctuation">}</span></code></pre><p>Reader 复用 Encoder 编码器将 changeset 集解码成<code>map[string]interface{}</code>格式，然后将它们合成一个 changeset。它通过格式来确定使用哪个解码器。合成的 changeset 中的<code>Values</code>可以转成 Go 类型值，而如果有值不能加载时，其中的值也可以作为回退值使用。</p><pre class="language-go"><code><span class="token comment" spellcheck="true">// Values is returned by the reader</span>
<span class="token keyword">type</span> Values <span class="token keyword">interface</span> <span class="token punctuation">{</span>
	<span class="token comment" spellcheck="true">// Return raw data</span>
        <span class="token function">Bytes</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span>
	<span class="token comment" spellcheck="true">// Retrieve a value</span>
        <span class="token function">Get</span><span class="token punctuation">(</span>path <span class="token operator">...</span><span class="token builtin">string</span><span class="token punctuation">)</span> Value
	<span class="token comment" spellcheck="true">// Return values as a map</span>
        <span class="token function">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
	<span class="token comment" spellcheck="true">// Scan config into a Go type</span>
        <span class="token function">Scan</span><span class="token punctuation">(</span>v <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">error</span>
<span class="token punctuation">}</span></code></pre><p><code>Value</code>接口支持使用构建、类型断言转化成 go 类型的值，默认使用回退值。</p><pre class="language-go"><code><span class="token keyword">type</span> Value <span class="token keyword">interface</span> <span class="token punctuation">{</span>
	<span class="token function">Bool</span><span class="token punctuation">(</span>def <span class="token builtin">bool</span><span class="token punctuation">)</span> <span class="token builtin">bool</span>
	<span class="token function">Int</span><span class="token punctuation">(</span>def <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token builtin">int</span>
	<span class="token function">String</span><span class="token punctuation">(</span>def <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">string</span>
	<span class="token function">Float64</span><span class="token punctuation">(</span>def <span class="token builtin">float64</span><span class="token punctuation">)</span> <span class="token builtin">float64</span>
	<span class="token function">Duration</span><span class="token punctuation">(</span>def time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span> time<span class="token punctuation">.</span>Duration
	<span class="token function">StringSlice</span><span class="token punctuation">(</span>def <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span>
	<span class="token function">StringMap</span><span class="token punctuation">(</span>def <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span>
	<span class="token function">Scan</span><span class="token punctuation">(</span>val <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">error</span>
	<span class="token function">Bytes</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span>
<span class="token punctuation">}</span></code></pre><h2 id="Config"><span>Config</span><a href="#Config" class="anchor">#</a></h2><p><code>Config</code>管理所有配置、抽象后的资源、编码器及 reader。</p><p>读取、同步、监视多个后台资源，把资源合并成单一集合以供查询。</p><pre class="language-go"><code><span class="token comment" spellcheck="true">// Config is an interface abstraction for dynamic configuration</span>
<span class="token keyword">type</span> Config <span class="token keyword">interface</span> <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">// provide the reader.Values interface</span>
        reader<span class="token punctuation">.</span>Values
	<span class="token comment" spellcheck="true">// Stop the config loader/watcher</span>
	<span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span>
	<span class="token comment" spellcheck="true">// Load config sources</span>
	<span class="token function">Load</span><span class="token punctuation">(</span>source <span class="token operator">...</span>source<span class="token punctuation">.</span>Source<span class="token punctuation">)</span> <span class="token builtin">error</span>
	<span class="token comment" spellcheck="true">// Force a source changeset sync</span>
	<span class="token function">Sync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span>
	<span class="token comment" spellcheck="true">// Watch a value for changes</span>
	<span class="token function">Watch</span><span class="token punctuation">(</span>path <span class="token operator">...</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>Watcher<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre><h2 id="使用方式"><span>使用方式</span><a href="#使用方式" class="anchor">#</a></h2><ul><li><p><a href="#简单示例">简单示例</a></p></li><li><p><a href="#新增配置实例">新增配置实例</a></p></li><li><p><a href="#加载配置">加载配置</a></p></li><li><p><a href="#读取全部配置">读取全部配置</a></p></li><li><p><a href="#读取指定配置">读取指定配置</a></p></li><li><p><a href="#监控配置">监控配置</a></p></li><li><p><a href="#使用多数据源">使用多数据源</a></p></li><li><p><a href="#设置源编码">设置源编码器</a></p></li><li><p><a href="#增加读编码">增加读编码器</a></p></li></ul><h3 id="简单示例"><span>简单示例</span><a href="#简单示例" class="anchor">#</a></h3><p>配置文件可以是 Encoder 解码器支持的任何格式：</p><p>JSON json config:</p><pre class="language-json"><code><span class="token punctuation">{</span>
  <span class="token property">"hosts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">"database"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token property">"address"</span><span class="token operator">:</span> <span class="token string">"10.0.0.1"</span><span class="token punctuation">,</span>
      <span class="token property">"port"</span><span class="token operator">:</span> <span class="token number">3306</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token property">"cache"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token property">"address"</span><span class="token operator">:</span> <span class="token string">"10.0.0.2"</span><span class="token punctuation">,</span>
      <span class="token property">"port"</span><span class="token operator">:</span> <span class="token number">6379</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre><h3 id="新增配置实例"><span>新增配置实例</span><a href="#新增配置实例" class="anchor">#</a></h3><p>新增配置（直接使用默认的配置对象也可）</p><pre class="language-go"><code><span class="token keyword">import</span> <span class="token string">"github.com/micro/go-micro/v2/config"</span>

conf <span class="token operator">:=</span> config<span class="token punctuation">.</span><span class="token function">NewConfig</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre><h3 id="加载配置"><span>加载配置</span><a href="#加载配置" class="anchor">#</a></h3><p>加载文件配置，文件的扩展名即为配置的格式。</p><pre class="language-go"><code><span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"github.com/micro/go-micro/v2/config"</span>
<span class="token punctuation">)</span>

<span class="token comment" spellcheck="true">// Load json config file</span>
config<span class="token punctuation">.</span><span class="token function">LoadFile</span><span class="token punctuation">(</span><span class="token string">"/tmp/config.json"</span><span class="token punctuation">)</span></code></pre><p>也可以是其它如 yaml、toml 或者 xml，看适当情况使用。</p><pre class="language-go"><code><span class="token comment" spellcheck="true">// Load yaml config file</span>
config<span class="token punctuation">.</span><span class="token function">LoadFile</span><span class="token punctuation">(</span><span class="token string">"/tmp/config.yaml"</span><span class="token punctuation">)</span></code></pre><p>如果没有扩展名时，则指定编码器</p><pre class="language-go"><code><span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">"github.com/micro/go-micro/v2/config"</span>
	<span class="token string">"github.com/micro/go-micro/v2/config/source/file"</span>
<span class="token punctuation">)</span>

enc <span class="token operator">:=</span> toml<span class="token punctuation">.</span><span class="token function">NewEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token comment" spellcheck="true">// Load toml file with encoder</span>
config<span class="token punctuation">.</span><span class="token function">Load</span><span class="token punctuation">(</span>file<span class="token punctuation">.</span><span class="token function">NewSource</span><span class="token punctuation">(</span>
        file<span class="token punctuation">.</span><span class="token function">WithPath</span><span class="token punctuation">(</span><span class="token string">"/tmp/config"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
	source<span class="token punctuation">.</span><span class="token function">WithEncoder</span><span class="token punctuation">(</span>enc<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">)</span></code></pre><h3 id="读取全部配置"><span>读取全部配置</span><a href="#读取全部配置" class="anchor">#</a></h3><p>读取全部配置</p><pre class="language-go"><code><span class="token comment" spellcheck="true">// retrieve map[string]interface{}</span>
conf <span class="token operator">:=</span> config<span class="token punctuation">.</span><span class="token function">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token comment" spellcheck="true">// map[cache:map[address:10.0.0.2 port:6379] database:map[address:10.0.0.1 port:3306]]</span>
fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>conf<span class="token punctuation">[</span><span class="token string">"hosts"</span><span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre><p>将配置写入结构</p><pre class="language-go"><code><span class="token keyword">type</span> Host <span class="token keyword">struct</span> <span class="token punctuation">{</span>
        Address <span class="token builtin">string</span> <span class="token string">`json:"address"`</span>
        Port <span class="token builtin">int</span> <span class="token string">`json:"port"`</span>
<span class="token punctuation">}</span>

<span class="token keyword">type</span> Config <span class="token keyword">struct</span><span class="token punctuation">{</span>
	Hosts <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>Host <span class="token string">`json:"hosts"`</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> conf Config

config<span class="token punctuation">.</span><span class="token function">Scan</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>conf<span class="token punctuation">)</span>

<span class="token comment" spellcheck="true">// 10.0.0.1 3306</span>
fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>conf<span class="token punctuation">.</span>Hosts<span class="token punctuation">[</span><span class="token string">"database"</span><span class="token punctuation">]</span><span class="token punctuation">.</span>Address<span class="token punctuation">,</span> conf<span class="token punctuation">.</span>Hosts<span class="token punctuation">[</span><span class="token string">"database"</span><span class="token punctuation">]</span><span class="token punctuation">.</span>Port<span class="token punctuation">)</span></code></pre><h3 id="读取指定配置"><span>读取指定配置</span><a href="#读取指定配置" class="anchor">#</a></h3><p>如果将配置写入结构</p><pre class="language-go"><code><span class="token keyword">type</span> Host <span class="token keyword">struct</span> <span class="token punctuation">{</span>
	Address <span class="token builtin">string</span> <span class="token string">`json:"address"`</span>
	Port <span class="token builtin">int</span> <span class="token string">`json:"port"`</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> host Host

config<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"hosts"</span><span class="token punctuation">,</span> <span class="token string">"database"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Scan</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>host<span class="token punctuation">)</span>

<span class="token comment" spellcheck="true">// 10.0.0.1 3306</span>
fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>host<span class="token punctuation">.</span>Address<span class="token punctuation">,</span> host<span class="token punctuation">.</span>Port<span class="token punctuation">)</span></code></pre><p>读取独立的值</p><pre class="language-go"><code><span class="token comment" spellcheck="true">// 获取address值，缺省值使用 “localhost”</span>
address <span class="token operator">:=</span> config<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"hosts"</span><span class="token punctuation">,</span> <span class="token string">"database"</span><span class="token punctuation">,</span> <span class="token string">"address"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token string">"localhost"</span><span class="token punctuation">)</span>

<span class="token comment" spellcheck="true">// 获取port值，缺省值使用 3000</span>
port <span class="token operator">:=</span> config<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"hosts"</span><span class="token punctuation">,</span> <span class="token string">"database"</span><span class="token punctuation">,</span> <span class="token string">"port"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Int</span><span class="token punctuation">(</span><span class="token number">3000</span><span class="token punctuation">)</span></code></pre><h3 id="监控配置"><span>监控配置</span><a href="#监控配置" class="anchor">#</a></h3><p>观测目录的变化。当文件有改动时，新值便可生效。</p><pre class="language-go"><code>w<span class="token punctuation">,</span> err <span class="token operator">:=</span> config<span class="token punctuation">.</span><span class="token function">Watch</span><span class="token punctuation">(</span><span class="token string">"hosts"</span><span class="token punctuation">,</span> <span class="token string">"database"</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
	<span class="token comment" spellcheck="true">// do something</span>
<span class="token punctuation">}</span>

<span class="token comment" spellcheck="true">// wait for next value</span>
v<span class="token punctuation">,</span> err <span class="token operator">:=</span> w<span class="token punctuation">.</span><span class="token function">Next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
	<span class="token comment" spellcheck="true">// do something</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> host Host

v<span class="token punctuation">.</span><span class="token function">Scan</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>host<span class="token punctuation">)</span></code></pre><h3 id="使用多数据源"><span>使用多数据源</span><a href="#使用多数据源" class="anchor">#</a></h3><p>多资源可以加载并合并，合并优先级顺序则是反向的，即后面导入的优先级高。</p><pre class="language-go"><code>config<span class="token punctuation">.</span><span class="token function">Load</span><span class="token punctuation">(</span>
	<span class="token comment" spellcheck="true">// base config from env</span>
	env<span class="token punctuation">.</span><span class="token function">NewSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
	<span class="token comment" spellcheck="true">// override env with flags</span>
	flag<span class="token punctuation">.</span><span class="token function">NewSource</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
	<span class="token comment" spellcheck="true">// override flags with file</span>
	file<span class="token punctuation">.</span><span class="token function">NewSource</span><span class="token punctuation">(</span>
		file<span class="token punctuation">.</span><span class="token function">WithPath</span><span class="token punctuation">(</span><span class="token string">"/tmp/config.json"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
	<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span></code></pre><h3 id="设置源编码器"><span>设置源编码器</span><a href="#设置源编码器" class="anchor">#</a></h3><p>资源需要编码器才能将配置编码与解码成所需的 changeset 格式。</p><p>默认编码器是 JSON 格式，也可以使用 yaml、xml、toml 等选项。</p><pre class="language-go"><code>e <span class="token operator">:=</span> yaml<span class="token punctuation">.</span><span class="token function">NewEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

s <span class="token operator">:=</span> consul<span class="token punctuation">.</span><span class="token function">NewSource</span><span class="token punctuation">(</span>
	source<span class="token punctuation">.</span><span class="token function">WithEncoder</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span></code></pre><h3 id="增加读编码器"><span>增加读编码器</span><a href="#增加读编码器" class="anchor">#</a></h3><p>Reader 使用各种编码器来解码不同格式源的数据。</p><p>默认的 Reader 支持 json、yaml、xml、toml、hcl，合并配置后会把其转成 json 格式。</p><p>也可指定给其特定的编码器：</p><pre class="language-go"><code>e <span class="token operator">:=</span> yaml<span class="token punctuation">.</span><span class="token function">NewEncoder</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

r <span class="token operator">:=</span> json<span class="token punctuation">.</span><span class="token function">NewReader</span><span class="token punctuation">(</span>
	reader<span class="token punctuation">.</span><span class="token function">WithEncoder</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span></code></pre><h2 id="常见问题"><span>常见问题</span><a href="#常见问题" class="anchor">#</a></h2><h3 id="与-Viper-有哪些不同？"><span>与 Viper 有哪些不同？</span><a href="#与-Viper-有哪些不同？" class="anchor">#</a></h3><p><a href="https://github.com/spf13/viper">Viper</a>与 go-config 都着力解决同样的问题，只是 Go-confi 使用不同的接口，并且它是 micro 工具生态中的一员。</p><h3 id="Encoder-和-Reader-有什么不同？"><span>Encoder 和 Reader 有什么不同？</span><a href="#Encoder-和-Reader-有什么不同？" class="anchor">#</a></h3><p>Encoder 编码器负责的是后台资源数据的编解码工作。而 Reader 则使用不同的 encoder 解码，解码的配置源可能有不同的格式，而这些 encoder 会解决这个事情并合并成单一编码格式。</p><p>如果是文件资源，则配置的解码器取决于文件的扩展名。</p><p>如果是基于 consul 的配置、etcd 或类似的键值对资源，则可能会从前缀中带有多个键（特定规则）的加载，也就是说资源需要明白编码，才能返回单一的变更集。</p><p>如果是环境变量、参数 flag，则会把这些值编码成 byte 数组，指定格式以备 reader 合并。</p><h3 id="为什么-changeset-变更集不是-mapstringinterface{}的格式？"><span>为什么 changeset 变更集不是 map<span>string</span>interface{}的格式？</span><a href="#为什么-changeset-变更集不是-mapstringinterface{}的格式？" class="anchor">#</a></h3><p>总有配置源数据不是键值对的情况，而 byte 数组的方式再解码给 Reader 更简单些。</p></section><section class="markdown api-container"></section></article><div class="contributors-list" style="display:flex;list-style:none;margin:0;padding:0"><span style="opacity:0.3" class="ant-avatar ant-avatar-circle"><span class="ant-avatar-string" style="opacity:0"></span></span></div></section><section class="prev-next-nav"></section><footer class="rc-footer rc-footer-dark"><section class="rc-footer-container"><section class="rc-footer-columns"><div class="rc-footer-column"><h2>相关资源</h2><div class="rc-footer-item"><a href="https://github.com/micro-in-cn/platform-web" target="_blank">Platform Web 治理平台</a></div><div class="rc-footer-item"><a href="https://github.com/micro-in-cn/XConf" target="_blank">XConf 配置中心</a></div></div><div class="rc-footer-column"><h2>社区</h2><div class="rc-footer-item"><a href="https://github.com/websemantics/awesome-ant-design" target="_blank"><span class="rc-footer-item-icon"><span role="img" aria-label="comment" class="anticon anticon-comment"><svg viewBox="64 64 896 896" focusable="false" class="" data-icon="comment" width="1em" height="1em" fill="currentColor" aria-hidden="true"><defs><style></style></defs><path d="M573 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40zm-280 0c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40z"></path><path d="M894 345a343.92 343.92 0 00-189-130v.1c-17.1-19-36.4-36.5-58-52.1-163.7-119-393.5-82.7-513 81-96.3 133-92.2 311.9 6 439l.8 132.6c0 3.2.5 6.4 1.5 9.4a31.95 31.95 0 0040.1 20.9L309 806c33.5 11.9 68.1 18.7 102.5 20.6l-.5.4c89.1 64.9 205.9 84.4 313 49l127.1 41.4c3.2 1 6.5 1.6 9.9 1.6 17.7 0 32-14.3 32-32V753c88.1-119.6 90.4-284.9 1-408zM323 735l-12-5-99 31-1-104-8-9c-84.6-103.2-90.2-251.9-11-361 96.4-132.2 281.2-161.4 413-66 132.2 96.1 161.5 280.6 66 412-80.1 109.9-223.5 150.5-348 102zm505-17l-8 10 1 104-98-33-12 5c-56 20.8-115.7 22.5-171 7l-.2-.1A367.31 367.31 0 00729 676c76.4-105.3 88.8-237.6 44.4-350.4l.6.4c23 16.5 44.1 37.1 62 62 72.6 99.6 68.5 235.2-8 330z"></path><path d="M433 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40z"></path></svg></span></span>讨论</a></div><div class="rc-footer-item"><a href="/docs/community/join-us-cn#加入我们"><span class="rc-footer-item-icon"><span role="img" aria-label="usergroup-add" class="anticon anticon-usergroup-add"><svg viewBox="64 64 896 896" focusable="false" class="" data-icon="usergroup-add" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M892 772h-80v-80c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v80h-80c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h80v80c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-80h80c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM373.5 498.4c-.9-8.7-1.4-17.5-1.4-26.4 0-15.9 1.5-31.4 4.3-46.5.7-3.6-1.2-7.3-4.5-8.8-13.6-6.1-26.1-14.5-36.9-25.1a127.54 127.54 0 01-38.7-95.4c.9-32.1 13.8-62.6 36.3-85.6 24.7-25.3 57.9-39.1 93.2-38.7 31.9.3 62.7 12.6 86 34.4 7.9 7.4 14.7 15.6 20.4 24.4 2 3.1 5.9 4.4 9.3 3.2 17.6-6.1 36.2-10.4 55.3-12.4 5.6-.6 8.8-6.6 6.3-11.6-32.5-64.3-98.9-108.7-175.7-109.9-110.8-1.7-203.2 89.2-203.2 200 0 62.8 28.9 118.8 74.2 155.5-31.8 14.7-61.1 35-86.5 60.4-54.8 54.7-85.8 126.9-87.8 204a8 8 0 008 8.2h56.1c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5 29.4-29.4 65.4-49.8 104.7-59.7 3.8-1.1 6.4-4.8 5.9-8.8zM824 472c0-109.4-87.9-198.3-196.9-200C516.3 270.3 424 361.2 424 472c0 62.8 29 118.8 74.2 155.5a300.95 300.95 0 00-86.4 60.4C357 742.6 326 814.8 324 891.8a8 8 0 008 8.2h56c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5C505.8 695.7 563 672 624 672c110.4 0 200-89.5 200-200zm-109.5 90.5C690.3 586.7 658.2 600 624 600s-66.3-13.3-90.5-37.5a127.26 127.26 0 01-37.5-91.8c.3-32.8 13.4-64.5 36.3-88 24-24.6 56.1-38.3 90.4-38.7 33.9-.3 66.8 12.9 91 36.6 24.8 24.3 38.4 56.8 38.4 91.4-.1 34.2-13.4 66.3-37.6 90.5z"></path></svg></span></span>加入我们</a></div></div><div class="rc-footer-column"><h2>帮助</h2><div class="rc-footer-item"><a href="https://github.com/micro-in-cn/questions" target="_blank"><span class="rc-footer-item-icon"><span role="img" aria-label="github" class="anticon anticon-github"><svg viewBox="64 64 896 896" focusable="false" class="" data-icon="github" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0138.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"></path></svg></span></span>GitHub</a></div></div><div class="rc-footer-column"><h2><span class="rc-footer-column-icon"><img src="https://gw.alipayobjects.com/zos/rmsportal/nBVXkrFdWHxbZlmMbsaH.svg" alt="Ant XTech"/></span>更多产品</h2><div class="rc-footer-item"><a href="https://yuque.com" target="_blank"><span class="rc-footer-item-icon"><img src="https://gw.alipayobjects.com/zos/rmsportal/XuVpGqBFxXplzvLjJBZB.svg" alt="yuque"/></span>语雀</a><span class="rc-footer-item-separator">-</span><span class="rc-footer-item-description">知识创作与分享工具</span></div></div></section></section><section class="rc-footer-bottom"><div class="rc-footer-bottom-container">Made with <span style="color:#fff">❤</span> by<!-- --> <a target="_blank" rel="noopener noreferrer" href="https://xtech.antfin.com">XTech</a></div></section></footer></div></div></div></div>
    </div>
    
    <script src="/index-c81a5111.js"></script>
    
    <!-- Global Site Tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-72788897-1"></script>
    <script>
      if (!location.port) {
        // Enable Google Analytics
        window.dataLayer = window.dataLayer || [];
        function gtag() {
          dataLayer.push(arguments);
        }
        gtag('js', new Date());
        gtag('config', 'UA-72788897-1');
      }
    </script>
    <!-- Hotjar Tracking Code for microhq.cn -->
    <script>
      (function (h, o, t, j, a, r) {
        h.hj =
          h.hj ||
          function () {
            (h.hj.q = h.hj.q || []).push(arguments);
          };
        h._hjSettings = { hjid: 1779539, hjsv: 6 };
        a = o.getElementsByTagName('head')[0];
        r = o.createElement('script');
        r.async = 1;
        r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
        a.appendChild(r);
      })(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
    </script>
  </body>
</html>
